package com.aqielife.demo.handler;



import com.aqelife.webflux.utils.CheckUtil;
import com.aqielife.demo.entity.User;
import com.aqielife.demo.repository.UserRepository;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.reactive.function.server.ServerResponse;
import reactor.core.publisher.Mono;

import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.http.MediaType.APPLICATION_JSON_UTF8;
import static org.springframework.web.reactive.function.BodyInserters.fromObject;
import static org.springframework.web.reactive.function.server.ServerResponse.notFound;
import static org.springframework.web.reactive.function.server.ServerResponse.ok;

@Component
public class UserHandler {

    private final UserRepository repository;

    public UserHandler(UserRepository rep) {
        this.repository = rep;
    }

    /**
     * 得到所有用户
     *
     * @param request
     * @return
     */
    public Mono<ServerResponse> getAllUser(ServerRequest request) {
        return ok().contentType(APPLICATION_JSON_UTF8)
                .body(this.repository.findAll(), User.class);
    }

    /**
     * 创建用户
     *
     * @param request
     * @return
     */
    public Mono<ServerResponse> createUser(ServerRequest request) {
        // 2.0.0 是可以工作, 但是2.0.1 下面这个模式是会报异常,不能调用block会阻塞线程,也会抛出异常
        Mono<User> user = request.bodyToMono(User.class);

        // Mono/Flush是流,是一个发布者,任何时候不能调用发布者的订阅方法subscribe
        // 消费必须交给springBoot消费
        return user.flatMap(u -> {
            // 校验代码需要放在这里
            CheckUtil.checkName(u.getName());

            return ok().contentType(APPLICATION_JSON_UTF8)
                    .body(this.repository.save(u), User.class);
        });
    }

    /**
     * 根据id删除用户
     *
     * @param request
     * @return
     */
    public Mono<ServerResponse> deleteUserById(ServerRequest request) {
        String id = request.pathVariable("id");

        return this.repository.findById(id)
                .flatMap(
                        user -> this.repository.delete(user).then(ok().build()))
                .switchIfEmpty(notFound().build());
    }

    public Mono<ServerResponse> findUserById(ServerRequest request) {
         String id = request.pathVariable("id");

        Mono<ServerResponse> serverResponseMono = repository.findById(id)
                .flatMap(user -> ok().contentType(APPLICATION_JSON).body(fromObject(user)))
                .switchIfEmpty(notFound().build());
        return serverResponseMono;
    }

}

